package com.ynet.middleground.contract.model;

import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;

import com.google.common.base.Throwables;
import com.ynet.core.common.BaseReqObj;
import com.ynet.core.common.PagerInfo;
import com.ynet.core.common.ServiceResult;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.core.util.IDUtil;
import com.ynet.middleground.user.bean.QueryOrganizationalStructureReq;
import com.ynet.middleground.user.bean.QueryUserInfoReq;
import com.ynet.middleground.user.dto.OrganizationalStructureDto;
import com.ynet.middleground.user.dto.UserInfoDto;
import com.ynet.middleground.user.service.OrganizationManagementService;
import com.ynet.middleground.user.service.UserService;

/**
 * @author liulx
 * @description 用户中心服务调用模块 <br />
 * @date 2020-04-02 17:08
 */
@Component
public class UserCenterModel {

    @Reference(version = "0.0.1")
    private UserService userService;

    @Reference(version = "0.0.1")
    private OrganizationManagementService organizationManagementService;

    /**
     * 查询用户信息
     *
     * @param userId 用户id
     * @param channel 渠道
     * @param operationUserId 操作人id
     * @param enterpriseId 用户所属企业 id
     * @return 查询用户信息
     */
    public UserInfoDto getUserInfo(Integer userId, String channel, Integer operationUserId, Integer enterpriseId) {
        QueryUserInfoReq req = new QueryUserInfoReq();
        req.setUserId(userId);
        req.setEnterpriseId(enterpriseId);
        req.setPagerInfo(new PagerInfo());
        req.setTraceId(IDUtil.getSecureRandomId());
        req.setChannel(channel);
        req.setOperationUserId(operationUserId);
        req.setRequestTime(new Date());
        ServiceResult<List<UserInfoDto>> serviceResult;
        try {
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务,reqParams: {}",
                req.toString());
            serviceResult = userService.queryUserInfo(req);
        } catch (BusinessException e) {
            throw new BusinessException(e.getMessage(), e.getCode());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            throw new BusinessException("用户中心服务调用失败", "ECCT0002");
        }
        List<UserInfoDto> result = getServiceResult(serviceResult);
        if (result == null || result.size() == 0) {
            throw new BusinessException("用户不存在", "ECCT0005");
        }
        return result.get(0);
    }

    /**
     * 查询用户信息 source
     *
     * @param userId 用户id
     * @param channel 渠道
     * @param operationUserId 操作人id
     * @param enterpriseId 用户所属企业 id
     * @return 查询用户信息
     */
    public UserInfoDto getUserInfoSource(Integer userId, String channel, Integer operationUserId,
        Integer enterpriseId) {
        QueryUserInfoReq req = new QueryUserInfoReq();
        req.setEnterpriseId(enterpriseId);
        req.setUserId(userId);
        req.setTraceId(IDUtil.getSecureRandomId());
        req.setPagerInfo(new PagerInfo());
        req.setOperationUserId(operationUserId);
        req.setRequestTime(new Date());
        req.setChannel(channel);
        ServiceResult<List<UserInfoDto>> serviceResult;
        try {
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务,reqParams: {}",
                req.toString());
            serviceResult = userService.queryUserInfo(req);
        } catch (BusinessException e) {
            throw new BusinessException(e.getMessage(), e.getCode());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            throw new BusinessException("用户中心服务调用失败", "ECCT0002");
        }
        List<UserInfoDto> result = getServiceResult(serviceResult);
        if (result == null || result.size() == 0) {
            return null;
        }
        return result.get(0);
    }

    /**
     * 查询用户信息(获取所有人的信息)
     *
     * @param channel 渠道
     * @param operationUserId 操作人id
     * @return 查询用户信息
     */
    public List<UserInfoDto> getAllUserInfo(String userName, String channel, Integer operationUserId) {
        QueryUserInfoReq req = new QueryUserInfoReq();
        req.setPagerInfo(new PagerInfo(1000000, 1));
        req.setTraceId(IDUtil.getSecureRandomId());
        req.setChannel(channel);
        req.setOperationUserId(operationUserId);
        req.setRequestTime(new Date());
        req.setUserName(userName);
        ServiceResult<List<UserInfoDto>> serviceResult;
        try {
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务,reqParams: {}",
                req.toString());
            serviceResult = userService.queryUserInfo(req);
        } catch (BusinessException e) {
            throw new BusinessException(e.getMessage(), e.getCode());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "合约中心调用查询用户信息服务异常, case: {}",
                Throwables.getStackTraceAsString(e));
            throw new BusinessException("用户中心服务调用失败", "ECCT0002");
        }
        List<UserInfoDto> result = getServiceResult(serviceResult);
        if (result == null || result.size() == 0) {
            throw new BusinessException("用户不存在", "ECCT0005");
        }
        return result;
    }

    /**
     * 根据组织机构id 查询业态是否有效
     * 
     * @param baseReqObj 基础请求信息
     * @param formatId 业态公司 id
     * @return 若返回不为空，则有效；否则未无效
     */
    public OrganizationalStructureDto getFormatOrgInfo(Integer formatId, BaseReqObj baseReqObj) {
        QueryOrganizationalStructureReq req = new QueryOrganizationalStructureReq();
        req.setOrganizationalId(formatId);
        // 仅查询公司
        req.setOrganizationalType("0");
        req.setPagerInfo(new PagerInfo());
        req.setTraceId(baseReqObj.getTraceId());
        req.setChannel(baseReqObj.getChannel());
        req.setOperationUserId(baseReqObj.getOperationUserId());
        req.setRequestTime(baseReqObj.getRequestTime());

        ServiceResult<List<OrganizationalStructureDto>> serviceResult;
        try {
            IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "合约中心调用「港内组织机构/部门查询（不包含该组织的员工数量）」服务,reqParams: {}", req.toString());
            serviceResult = organizationManagementService.queryOrganizationalStructureInfo(req);
        } catch (BusinessException e) {
            throw new BusinessException(e.getMessage(), e.getCode());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(),
                "合约中心调用「港内组织机构/部门查询（不包含该组织的员工数量）」服务异常, case: {}", Throwables.getStackTraceAsString(e));
            throw new BusinessException("用户中心服务调用失败", "ECCT0002");
        }
        List<OrganizationalStructureDto> result = getServiceResult(serviceResult);
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(),
            "合约中心调用「港内组织机构/部门查询（不包含该组织的员工数量）」服务,result: {}", result.toString());
        if (result == null || result.isEmpty()) {
            throw new BusinessException("业态 id 有误，请检查！", "ECCT0007");
        }
        return result.get(0);
    }

    /**
     * 获取 ServiceResult 结果值
     *
     * @param serviceResult 服务返回结果对象
     * @param <T> 返回对象数据中具体的数据类型
     * @return ServiceResult 结果值
     */
    private <T> T getServiceResult(ServiceResult<T> serviceResult) {
        Optional.ofNullable(serviceResult).orElseThrow(() -> new BusinessException("用户中心服务调用失败", "ECCT0002"));
        if (serviceResult.isSuccess()) {
            return serviceResult.getResult();
        }
        throw new BusinessException(serviceResult.getErrorMsg(), serviceResult.getErrorCode());
    }

}
